package com.example.oauth2authserver.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.oauth2authserver.model.OAuthClientDetail;
import com.example.oauth2authserver.model.User;
import com.example.oauth2authserver.service.IOAuthClientDetailService;
import com.example.oauth2authserver.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.Map;

@RestController
@Slf4j
public class HomeController {
    @Autowired
    private IUserService userService;
    @Autowired
    private IOAuthClientDetailService clientDetailService;

    @GetMapping(value = "/product/{id}")
    @PreAuthorize("hasAuthority('ROLE_USER')")
    public ResponseEntity<String> getProduct(@PathVariable("id") final String id){
        return new ResponseEntity<>("Product id: " + id, HttpStatus.OK);
    }

    @GetMapping(value = "/order/{id}")
    @PreAuthorize("hasAuthority('ROLE_ADMIN')")
    public ResponseEntity<String> getOrder(@PathVariable("id") final String id){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        log.info("Authentication: " + authentication.getAuthorities().toString());
        return new ResponseEntity<>("Order id: " + id,HttpStatus.OK);
    }

    @GetMapping(value = "/getPrincipal")
    public ResponseEntity<OAuth2Authentication> getPrincipal(OAuth2Authentication oAuth2Authentication, Principal principal,Authentication authentication){
        log.info(oAuth2Authentication.toString());
        log.info("principal.toString(): " + principal.toString());
        log.info("principal.getName(): " + principal.getName());
        log.info("authetication: " + authentication.getAuthorities().toString());
        return new ResponseEntity<>(oAuth2Authentication,HttpStatus.OK);
    }

    @PostMapping(value = "/registry")
    public ResponseEntity<User> createUser(@RequestBody Map<String,Object> payload){
        String username = payload.get("username").toString();
        String password = payload.get("password").toString();
        if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
            User user = userService.create(username, password);
            return new ResponseEntity<>(user,HttpStatus.OK);
        }else{
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        }
    }

    @PostMapping(value = "/saveOAuthClientDetail",produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Void> saveOAuthClientDetail(@RequestBody OAuthClientDetail oAuthClientDetail){
        if (StringUtils.hasText(oAuthClientDetail.getClientSecret())) {
            String password = "{bcrypt}" + new BCryptPasswordEncoder().encode(oAuthClientDetail.getClientSecret());
            oAuthClientDetail.setClientSecret(password);
        }
        clientDetailService.create(oAuthClientDetail);
        return new ResponseEntity<>(HttpStatus.OK);
    }
}
